import os
import requests
import re
import json
from bs4 import BeautifulSoup
from datetime import datetime, timedelta, date
import utils
from interceptor.unifty_result import MyException
from model.datemodel import DateClass

# 匹配m月d1日至d2日放假 或则 m1月d1日至m2月d2日放假
holiday_pattern = re.compile(r'(\d{1,2}月\d{1,2}日(?:至(\d{1,2}月\d{1,2}日|\d{1,2}日))?)放假')
# 匹配m月d1日至d2日放假 或则 m1月d1日至m2月d2日上班
work_pattern = re.compile(r'。(\d{1,2}月\d{1,2}日(?:、\d{1,2}月\d{1,2}日)?上班)。')


# 根据配置读取url
def htm_url(year):
    try:
        with open('./config/config.json', 'r') as file:
            config = json.load(file)
        return config[str(year)]
    except Exception as e:
        return None


# 抓取页面数据
def crawl_html_data(year):
    url = htm_url(year)
    start_date = date(year, 1, 1)
    end_date = date(year, 12, 31)
    date_set = set()
    if url is None:
        current_date = start_date
        while current_date <= end_date:
            current = DateClass(current_date)
            current.gregorian = utils.get_gregorian_festival(current_date)
            current.lunar = utils.get_lunar_festival(current_date)
            if current_date.weekday() in [5, 6]:
                current.week = True
            date_set.add(current)
            current_date += timedelta(days=1)
    else:
        req = requests.get(url)
        req.encoding = req.apparent_encoding
        soup = BeautifulSoup(req.text, "html.parser")
        holiday_info = soup.find_all("p")
        text = ""
        for item in holiday_info:
            text += item.text.strip()
        text = re.sub(r'（(.*?)）', '', text)
        ext_holidays = extract_holidays(text, year)
        working_days = extract_working_days(text, year)
        current_date = start_date
        while current_date <= end_date:
            current = DateClass(current_date)
            current.gregorian = utils.get_gregorian_festival(current_date)
            current.lunar = utils.get_lunar_festival(current_date)
            if current_date.weekday() in [5, 6]:
                current.week = True
            if str(current_date) in ext_holidays:
                current.holiday = True
            if str(current_date) in working_days and current_date.weekday() in [5, 6]:
                current.adjustment = True
            date_set.add(current)
            current_date += timedelta(days=1)
        write_json_to_records_file(year)
    date_list = [d.to_dict() for d in date_set]
    date_list.sort(key=lambda x: x["date"])
    write_json_to_file(year, date_list)
    return json.dumps(date_list)


# 获取法定节假日
def extract_holidays(text, target_year):
    holidays = holiday_pattern.findall(text)
    holiday_dates = []
    for date_str, end_date_str in holidays:
        if '至' in date_str:
            start_date_str, end_date_str = date_str.split('至')
            start_month, start_day = map(int, re.findall(r'\d{1,2}', start_date_str))
            end_month, end_day = (start_month, int(end_date_str.split('日')[0])) if '月' not in end_date_str else map(
                int, re.findall(r'\d{1,2}', end_date_str))
            date_range = [datetime(target_year, start_month, start_day) + timedelta(days=i) for i in range(
                (datetime(target_year, end_month, end_day) - datetime(target_year, start_month, start_day)).days + 1)]
            for date_item in date_range:
                holiday_dates.append(date_item.strftime('%Y-%m-%d'))
        else:
            month, day = map(int, re.findall(r'\d{1,2}', date_str))
            holiday_dates.append(datetime(target_year, month, day).strftime('%Y-%m-%d'))
    return holiday_dates


# 获取工作日期
def extract_working_days(text, target_year):
    work_days_str = work_pattern.findall(text)
    work_day_list = []
    for work_day_str in work_days_str:
        work_data_replace = re.sub('上班', '', work_day_str)
        work_data_parts = re.split('、', work_data_replace)
        for part in work_data_parts:
            work_day_list.append(zh_time_format(part, target_year))
    return work_day_list


# 日期格式转换（m月d日=> y-m-n）
def zh_time_format(work_day, target_year):
    datetime_obj = datetime.strptime(str(target_year) + "年" + work_day, '%Y年%m月%d日')
    return datetime_obj.strftime('%Y-%m-%d')


# 移除和
def remove_bracket(days):
    return str([str(date_item) for date_item in days]).replace('[', '').replace(']', '')


# 把字符串写入json文件
def write_json_to_file(year, date_list):
    try:
        with open(f'./data/{year}.json', 'w', encoding='utf-8') as file:
            json_str = json.dumps(date_list, indent=4, ensure_ascii=False)
            file.write(json_str)
    except Exception as e:
        raise MyException("文件写入失败") from e


# 把字符串写入json文件
def write_json_to_records_file(year):
    try:
        # 打开配置文件
        with open('config/record.json', 'r') as file:
            try:
                config = json.load(file)
            except json.JSONDecodeError:
                config = {}
            # 处理数据逻辑
            config[str(year)] = True
        with open(f'config/record.json', 'w', encoding='utf-8') as file:
            json_str = json.dumps(config, indent=4, ensure_ascii=False)
            file.write(json_str)
    except Exception as e:
        raise MyException("文件写入失败") from e


# 把字符串写入json文件
def get_record(year):
    try:
        # 打开配置文件
        with open('config/record.json', 'r') as file:
            try:
                config = json.load(file)
            except json.JSONDecodeError:
                config = {}
        return bool(config[str(year)])
    except Exception as e:
        return False


# 根据文件路径读取，如果异常返回空
def read_file(year):
    file_name = f"./data/{year}.json"
    if os.path.exists(file_name):
        try:
            with open(file_name, 'r', encoding='utf-8') as file:
                return json.loads(file.read())
        except FileNotFoundError:
            return None
        except IOError as e:
            return None
    else:
        return None
